---
layout: docs
page_title: Establish Cluster Peering Connections
description: >-
  Generate a peering token to establish communication, export services, and authorize requests for cluster peering connections. Learn how to establish peering connections with Consul's HTTP API, CLI or UI.
---

# Establish cluster peering connections

This page details the process for establishing a cluster peering connection between services deployed to different datacenters. You can interact with Consul's cluster peering features using the CLI, the HTTP API, or the UI. The overall process for establishing a cluster peering connection consists of the following steps:

1. Create a peering token in one cluster.
1. Use the peering token to establish peering with a second cluster.
1. Export services between clusters.
1. Create intentions to authorize services for peers.

Cluster peering between services cannot be established until all four steps are complete.

For Kubernetes guidance, refer to [Establish cluster peering connections on Kubernetes](/consul/docs/k8s/connect/cluster-peering/usage/establish-peering). For HCP Consul guidance, refer to [Establish cluster peering connections on HCP Consul](/hcp/docs/consul/usage/cluster-peering/create-connections).

## Requirements

You must meet the following requirements to use cluster peering:

- Consul v1.14.1 or higher
- Services hosted in admin partitions on separate datacenters

If you need to make services available to an admin partition in the same datacenter, do not use cluster peering. Instead, use the [`exported-services` configuration entry](/consul/docs/connect/config-entries/exported-services) to make service upstreams available to other admin partitions in a single datacenter.

### Mesh gateway requirements

Consul's default configuration supports cluster peering connections directly between clusters. In production environments, we recommend using mesh gateways to securely route service mesh traffic between partitions with cluster peering connections.

To enable cluster peering through mesh gateways and configure mesh gateways to support cluster peering, refer to [mesh gateway specifications](/consul/docs/connect/cluster-peering/tech-specs#mesh-gateway-specifications).

## Create a peering token

To begin the cluster peering process, generate a peering token in one of your clusters. The other cluster uses this token to establish the peering connection.

Every time you generate a peering token, a single-use secret for establishing the secret is embedded in the token. Because regenerating a peering token invalidates the previously generated secret, you must use the most recently created token to establish peering connections.

<Tabs>
<Tab heading="Consul CLI" group="cli">

1. In `cluster-01`, use the [`consul peering generate-token` command](/consul/commands/peering/generate-token) to issue a request for a peering token.

  ```shell-session
  $ consul peering generate-token -name cluster-02
  ```

  The CLI outputs the peering token, which is a base64-encoded string containing the token details.

1. Save this value to a file or clipboard to use in the next step on `cluster-02`.

</Tab>
<Tab heading="HTTP API" group="api">

1. In `cluster-01`, use the [`/peering/token` endpoint](/consul/api-docs/peering#generate-a-peering-token) to issue a request for a peering token.

  ```shell-session
  $ curl --request POST --data '{"Peer":"cluster-02"}' --url http://localhost:8500/v1/peering/token
  ```

  The CLI outputs the peering token, which is a base64-encoded string containing the token details.

1. Create a JSON file that contains the first cluster's name and the peering token.

  <CodeBlockConfig filename="peering_token.json" hideClipboard>

  ```json
  {
    "Peer": "cluster-01",
    "PeeringToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImF1ZCI6IlNvbHIifQ.5T7L_L1MPfQ_5FjKGa1fTPqrzwK4bNSM812nW6oyjb8"
  }
  ```

  </CodeBlockConfig>

</Tab>
<Tab heading="Consul UI" group="ui">

To begin the cluster peering process, generate a peering token in one of your clusters. The other cluster uses this token to establish the peering connection.

Every time you generate a peering token, a single-use secret for establishing the secret is embedded in the token. Because regenerating a peering token invalidates the previously generated secret, you must use the most recently created token to establish peering connections.

1. In the Consul UI for the datacenter associated with `cluster-01`, click **Peers**.
1. Click **Add peer connection**.
1. In the **Generate token** tab, enter `cluster-02` in the **Name of peer** field.
1. Click the **Generate token** button.
1. Copy the token before you proceed. You cannot view it again after leaving this screen. If you lose your token, you must generate a new one.

</Tab>
</Tabs>

## Establish a connection between clusters

Next, use the peering token to establish a secure connection between the clusters.

<Tabs>
<Tab heading="Consul CLI" group="cli">

1. In one of the client agents deployed to "cluster-02," issue the [`consul peering establish` command](/consul/commands/peering/establish) and specify the token generated in the previous step.

  ```shell-session
  $ consul peering establish -name cluster-01 -peering-token token-from-generate
  "Successfully established peering connection with cluster-01"
  ```

When you connect server agents through cluster peering, they peer their default partitions. To establish peering connections for other partitions through server agents, you must add the `-partition` flag to the `establish` command and specify the partitions you want to peer. For additional configuration information, refer to [`consul peering establish` command](/consul/commands/peering/establish).

You can run the `peering establish` command once per peering token. Peering tokens cannot be reused after being used to establish a connection. If you need to re-establish a connection, you must generate a new peering token.

</Tab>
<Tab heading="HTTP API" group="api">

1. In one of the client agents in "cluster-02," use `peering_token.json` and the [`/peering/establish` endpoint](/consul/api-docs/peering#establish-a-peering-connection) to establish the peering connection. This endpoint does not generate an output unless there is an error.

  ```shell-session
  $ curl --request POST --data @peering_token.json http://127.0.0.1:8500/v1/peering/establish
  ```

When you connect server agents through cluster peering, their default behavior is to peer to the `default` partition. To establish peering connections for other partitions through server agents, you must add the `Partition` field to `peering_token.json` and specify the partitions you want to peer. For additional configuration information, refer to [Cluster Peering - HTTP API](/consul/api-docs/peering).

You can dial the `peering/establish` endpoint once per peering token. Peering tokens cannot be reused after being used to establish a connection. If you need to re-establish a connection, you must generate a new peering token.

</Tab>

<Tab heading="Consul UI" group="ui">

1. In the Consul UI for the datacenter associated with `cluster 02`, click **Peers** and then **Add peer connection**.
1. Click **Establish peering**.
1. In the **Name of peer** field, enter `cluster-01`. Then paste the peering token in the **Token** field.
1. Click **Add peer**.

</Tab>
</Tabs>

## Export services between clusters

After you establish a connection between the clusters, you need to create an `exported-services` configuration entry that defines the services that are available for other clusters. Consul uses this configuration entry to advertise service information and support service mesh connections across clusters. 

An `exported-services` configuration entry makes services available to another admin partition. While it can target admin partitions either locally or remotely. Clusters peers always export services to remote partitions. Refer to [exported service consumers](/consul/docs/connect/config-entries/exported-services#consumers-1) for more information.

You must use the Consul CLI to complete this step. The HTTP API and the Consul UI do not support `exported-services` configuration entries.

<Tabs>
<Tab heading="Consul CLI" group="cli">

1. Create a configuration entry and specify the `Kind` as `"exported-services"`.

  <CodeBlockConfig filename="peering-config.hcl" hideClipboard>

  ```hcl
  Kind = "exported-services"
  Name = "default"
  Services = [
    {
      ## The name and namespace of the service to export.
      Name      = "service-name"
      Namespace = "default"

      ## The list of peer clusters to export the service to.
      Consumers = [
        {
          ## The peer name to reference in config is the one set
          ## during the peering process.
          Peer = "cluster-02"
        }
      ]
    }
  ]
  ```

  </CodeBlockConfig>

1. Add the configuration entry to your cluster.

  ```shell-session
  $ consul config write peering-config.hcl
  ```

Before you proceed, wait for the clusters to sync and make services available to their peers. To check the peered cluster status, [read the cluster peering connection](/consul/docs/connect/cluster-peering/usage/manage-connections#read-a-peering-connection).

</Tab>
</Tabs>

## Authorize services for peers

Before you can call services from peered clusters, you must set service intentions that authorize those clusters to use specific services. Consul prevents services from being exported to unauthorized clusters.

You must use the HTTP API or the Consul CLI to complete this step. The Consul UI supports intentions for local clusters only.

<Tabs>
<Tab heading="Consul CLI" group="cli">

1. Create a configuration entry and specify the `Kind` as `"service-intentions"`. Declare the service on "cluster-02" that can access the service in "cluster-01." In the following example, the service intentions configuration entry authorizes the `backend-service` to communicate with the `frontend-service` that is hosted on remote peer `cluster-02`:

  <CodeBlockConfig filename="peering-intentions.hcl" hideClipboard>

  ```hcl
  Kind      = "service-intentions"
  Name      = "backend-service"

  Sources = [
    {
      Name   = "frontend-service"
      Peer   = "cluster-02"
      Action = "allow"
    }
  ]
  ```

  </CodeBlockConfig>

  If the peer's name is not specified in `Peer`, then Consul assumes that the service is in the local cluster.

1. Add the configuration entry to your cluster.

  ```shell-session
  $ consul config write peering-intentions.hcl
  ```

</Tab>
<Tab heading="HTTP API" group="api">

1. Create a configuration entry and specify the `Kind` as `"service-intentions"`. Declare the service on "cluster-02" that can access the service in "cluster-01." In the following example, the service intentions configuration entry authorizes the `backend-service` to communicate with the `frontend-service` that is hosted on remote peer `cluster-02`:

  <CodeBlockConfig filename="peering-intentions.hcl" hideClipboard>

  ```hcl
  Kind      = "service-intentions"
  Name      = "backend-service"

  Sources = [
    {
      Name   = "frontend-service"
      Peer   = "cluster-02"
      Action = "allow"
    }
  ]
  ```

  </CodeBlockConfig>

  If the peer's name is not specified in `Peer`, then Consul assumes that the service is in the local cluster.

1. Add the configuration entry to your cluster.

  ```shell-session
  $ curl --request PUT --data @peering-intentions.hcl http://127.0.0.1:8500/v1/config
  ```

</Tab>
</Tabs>

### Authorize service reads with ACLs

If ACLs are enabled on a Consul cluster, sidecar proxies that access exported services as an upstream must have an ACL token that grants read access.

Read access to all imported services is granted using either of the following rules associated with an ACL token:

- `service:write` permissions for any service in the sidecar's partition.
- `service:read` and `node:read` for all services and nodes, respectively, in sidecar's namespace and partition.
  
For Consul Enterprise, the permissions apply to all imported services in the service's partition. These permissions are satisfied when using a [service identity](/consul/docs/security/acl/acl-roles#service-identities).

Refer to [Reading servers](/consul/docs/connect/config-entries/exported-services#reading-services) in the `exported-services` configuration entry documentation for example rules.

For additional information about how to configure and use ACLs, refer to [ACLs system overview](/consul/docs/security/acl).